(function($) {

var titre = document.title,
	colors  = ["green", "orange", "yellow", "red", "fuschia", "blue"],
	channel = nodeChat.connect("/chat"),
	log = null,
	message = null;

$(function() {
	log = $("#chat-log");
	message = $("#message");
	
	// Ajout d'un bouton facilement stylisable
	$("<a></a>", {
		id: "submit",
		text: "Send",
		href: "#",
		click: function(event) {
			event.preventDefault();
			$(this).closest("form").submit();
		}
	})
	.appendTo("#entry fieldset");
	
	// TODO Déconnection
	$("#users").delegate("li", "click", function() {
		message
			.val($(this).text() + ": " + message.val())
			.focus();
	});
});

// Un nouveau message a été posté sur le canal
// - Ajout à la fenêtre de discussion
$(channel).bind("msg", function(event, message) {
	var time = formatTime(message.timestamp),
		row = $("<div></div>")
			.addClass("chat-msg");
	
	$("<span></span>")
		.addClass("chat-time")
		.text(time)
		.appendTo(row);
	
	$("<span></span>")
		.addClass("chat-nick")
		.text(message.nick)
		.appendTo(row);
	
	$("<span></span>")
		.addClass("chat-text")
		.text(message.text)
		.appendTo(row);
	
	row.appendTo(log);
})

// Un autre utilisateur rejoint le canal
// - Ajouter à la fenêtre de discussion
.bind("join", function(event, message) {
	
	var time = formatTime(message.timestamp),
		row = $("<div></div>")
			.addClass("chat-msg chat-system-msg");
	$("<span></span>")
		.addClass("chat-time")
		.text(time)
		.appendTo(row);
	
	$("<span></span>")
		.addClass("chat-nick")
		.text(message.nick)
		.appendTo(row);
	
	$("<span></span>")
		.addClass("chat-text")
		.text("a rejoint le chan")
		.appendTo(row);
	
	row.appendTo(log);
})
// Un autre utilisateur rejoint le canal
// - Ajouter à la liste des utilisateurs
.bind("join", function(event, message) {
	var added = false,
		nick  = $("<li></li>", {
			"class": colors[0],
			text: message.nick
		});
	colors.push(colors.shift());
	$("#users > li").each(function() {
		if (message.nick == this.innerHTML) {
			added = true;
			return false;
		}
		if (message.nick < this.innerHTML) {
			added = true;
			nick.insertBefore(this);
			return false;
		}
	});
	if (!added) {
		$("#users").append(nick);
	}
})

// Un autre utilisateur quitte le canal
// - Ajouter à la fenêtre de discussion
.bind("part", function(event, message) {
	var time = formatTime(message.timestamp),
		row = $("<div></div>")
			.addClass("chat-msg chat-system-msg");
	
	$("<span></span>")
		.addClass("chat-time")
		.text(time)
		.appendTo(row);
	
	$("<span></span>")
		.addClass("chat-nick")
		.text(message.nick)
		.appendTo(row);
	
	$("<span></span>")
		.addClass("chat-text")
		.text("left the room")
		.appendTo(row);
	
	row.appendTo(log);
})

// Un autre utilisateur quitte le canal
// - Supprimer de la liste des utilisateurs
.bind("part", function(event, message) {
	$("#users > li").each(function() {
		if (this.innerHTML == message.nick) {
			$(this).remove();
			return false;
		}
	});
})

// Liste déroulante automatiquement en bas
.bind("join part msg", function() {
	// Défiler automatiquement si nous sommes à moins de 50 pixels du bas
	if (log.scrollTop() + 50 >= log[0].scrollHeight - log.height()) {
		window.setTimeout(function() {
			log.scrollTop(log[0].scrollHeight);
		}, 10);
	}
});

// Sélection d'un pseudo
$(function() {
	function loginError(error) {
		login
			.addClass("error")
			.find("label")
				.text(error + " Merci de choisir un autre pseudo:")
			.end()
			.find("input")
				.focus();
	}
	
	var login = $("#login");
	login.submit(function() {
		var nick = $.trim($("#nick").val());
		
		if (!nick.length || !/^[a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$/.test(nick)) {
			loginError("Nom d'utilisateur invalide.");
			return false;
		}
		
		channel.join(nick, {
			success: function() {
				$("body")
					.removeClass("login")
					.addClass("channel");
				message.focus();
			},
			error: function() {
				loginError("Pseudo déjà utilisé.");
			}
		});
		
		return false;
	});
	login.find("input").focus();
});

// Envoi des messages
$(function() {
	$("#channel form").submit(function() {
		channel.send(message.val());
		message.val("").focus();
		
		return false;
	});
});

// mettre à jour le titre de la page pour montrer s'il y a des messages non lus
$(function() {
	var focused = true,
		nonLus = 0;
	
	$(window)
		.blur(function() {
			focused = false;
		})
		.focus(function() {
			focused = true;
			nonLus = 0;
			document.title = titre;
		});
	
	$(channel).bind("msg", function(event, message) {
		if (!focused) {
			nonLus++;
			document.title = "(" + nonLus + ") " + titre;
		}
	});
});

// informer le serveur de chat que nous partons si nous fermons la fenêtre
$(window).unload(function() {
	channel.part();
});

function formatTime(timestamp) {
	var date = new Date(timestamp),
		heure = date.getHours(),
		minutes = date.getMinutes();
	
	if (minutes < 10) {
		minutes = "0" + minutes;
	}
	
	return heure + ":" + minutes;
}

})(jQuery);
